package com.cxj.g8llk;

import java.util.Iterator;
import java.util.LinkedList;

import org.loon.framework.android.game.action.sprite.StatusBar;
import org.loon.framework.android.game.core.graphics.Screen;
import org.loon.framework.android.game.core.graphics.component.LMessage;
import org.loon.framework.android.game.core.graphics.component.LPaper;
import org.loon.framework.android.game.core.graphics.opengl.GLColor;
import org.loon.framework.android.game.core.graphics.opengl.GLEx;
import org.loon.framework.android.game.core.input.LTouch;
import org.loon.framework.android.game.core.timer.LTimer;
import org.loon.framework.android.game.core.timer.LTimerContext;

import com.huawei.boss.statemachine.Action;
import com.huawei.boss.statemachine.State;
import com.huawei.boss.statemachine.StateMachine;

public class G8llkScreen extends Screen {
    private int offsetX = 0;
    private int offsetY = 0;
    private int stageNo;
    private com.cxj.g8llk.Grids grids;
    private Grid priv;
    private Grid curr;
    private LinkedList<Grid> path = new LinkedList<Grid>();
    private LTimer timer1 = new LTimer(50);
    private LMessage mes;
    private LTimer progresstimer = new LTimer(100);
    private int progress_number = 300;
    private StatusBar progress;
    private LPaper over;

    private StateMachine stateMachine = new StateMachine();

    enum STATE {
        INIT, READY, RUNNING, END, UNKNOWN
    };

    public G8llkScreen() {
        //定义状态
        State init = new State(STATE.INIT);
        State ready = new State(STATE.READY);
        State running = new State(STATE.RUNNING);
        State end = new State(STATE.END);

        init.addAction("load", new Action() {
            @Override
            public void call(Object... params) {
                setBackground(RSL.one().getImage(10));
                stageNo = 1;
                reset();
                stateMachine.gotoState(STATE.READY);
            }
        });

        ready.addAction("start", new Action() {
            @Override
            public void call(Object... params) {
                mes.setVisible(false);

                progress = new StatusBar(progress_number, progress_number, 325, 5, 150, 25);
                progress.setDead(true);
                G8llkScreen.this.add(progress);
                stateMachine.gotoState(STATE.RUNNING);
            }
        });

        running.addAction("reset", new Action() {
            @Override
            public void call(Object... params) {
                reset();
                stateMachine.gotoState(STATE.READY);
            }
        });

        running.addAction("click", new Action() {
            @Override
            public void call(Object... params) {
                curr = grids.getGrid(G8llkScreen.this, getTouchX(), getTouchY());
                if (curr == null || curr.isPassable()) {
                    RSL.one().getSound(8).play();
                    if (priv != null) {
                        priv.setBorder(3);
                    }
                    priv = null;
                    curr = null;
                    return;
                }
                if (priv == null) {
                    priv = curr;
                    priv.setBorder(0);
                    RSL.one().getSound(6).play();
                    return;
                }

                if (grids.checkPath(priv, curr, path)) {
                    RSL.one().getSound(0).play();
                    clearPair(path);
                    
                    if(grids.isClear())
                    {
                        //win
                        stageNo++;
                        stateMachine.receive("reset");
                    }
                    
                    LinkedList<Grid> pt = new LinkedList<Grid>();
                    if (!grids.findPath(pt)) {
                        stateMachine.receive("reset");
                    }
                } else {
                    RSL.one().getSound(8).play();
                }
                if (priv != null) {
                    priv.setBorder(3);
                }
                if (curr != null) {
                    curr.setBorder(3);
                }
                priv = null;
                curr = null;
            }
        });

        running.addAction("over", new Action() {
            @Override
            public void call(Object... params) {
                stateMachine.gotoState(STATE.END);
            }
        });

        running.addAction("loadprogress", new Action() {
            @Override
            public void call(Object... params) {
                if (progress != null) {
                    progress.setUpdate(progress.getValue() - 1);
                    if (progress.getValue() <= 5) {
                        getSprites().setVisible(false);

                        over = new LPaper(RSL.one().getImage(16), 0, 0) {
                            public void doClick() {
                                stateMachine.receive("restart");
                            }
                        };
                        over.setAlpha(0.1f);
                        centerOn(over);
                        over.setY(0);
                        add(over);
                        stateMachine.receive("over");
                    }
                }
            }
        });

        end.addAction("loadover", new Action() {
            @Override
            public void call(Object... params) {
                if (over.getY() < (getHeight() - over.getHeight()) / 2) {
                    over.move_down(8);
                    over.validatePosition();

                } else if (over.getAlpha() < 1.0f) {
                    over.setAlpha(over.getAlpha() + 0.1f);
                } else {
                    centerOn(over);
                }
            }
        });

        end.addAction("restart", new Action() {
            @Override
            public void call(Object... params) {
                if (over.getAlpha() >= 1.0) {
                    over.setVisible(false);
                    over = null;
                    removeAll();
                    stageNo=1;
                    reset();
                    getSprites().setVisible(true);
                    stateMachine.gotoState(STATE.READY);
                }
            }
        });

        stateMachine.register(STATE.INIT, init);
        stateMachine.register(STATE.RUNNING, running);
        stateMachine.register(STATE.READY, ready);
        stateMachine.register(STATE.END, end);
        stateMachine.ready(STATE.INIT);
    }

    public void onLoad() {
        stateMachine.receive("load");
    }

    private void reset() {
        path.clear();
        grids = new Grids(stageNo);
        getSprites().clear();
        
        grids.init(this);
        addStartMessage();
    }

    private void addStartMessage() {
        mes = new LMessage(RSL.one().getImage(14), (getWidth() - 460) / 2, getHeight() - 126 - 10) {
            public void doClick() {
                stateMachine.receive("start");
            }
        };
        mes.setMessageLength(20);
        mes.setAlpha(0.8f);
        mes.setFontColor(GLColor.black);
        mes.setMessage("游戏开始啦~~");
        add(mes);
    }

    @Override
    public void draw(GLEx g) {
    }

    @Override
    public void alter(LTimerContext t) {
        if (timer1.action(t.getTimeSinceLastUpdate())) {
            stateMachine.receive("loadover");
        }

        if (progresstimer.action(t.getTimeSinceLastUpdate())) {
            stateMachine.receive("loadprogress");
        }
    }

    @Override
    public void touchDown(LTouch e) {
        stateMachine.receive("click", e);
    }

    private void clearPair(LinkedList<Grid> pt) {
        AnimateThread thread = new AnimateThread(pt);
        thread.setPriority(Thread.NORM_PRIORITY);
        thread.run();//TODO
    }

    @Override
    public void touchUp(LTouch e) {
    }

    @Override
    public void touchMove(LTouch e) {
    }
    
    private class AnimateThread extends Thread {

        private LinkedList<Grid> tmp;

        public AnimateThread(LinkedList<Grid> temp) {
            tmp = temp;
        }

        public void run() {
            Grid g1 = tmp.get(0);
            Grid g4 = tmp.get(3);

            g1.setData(-1);
            g4.setData(-1);

            LinkedList<Grid> tmpgs = new LinkedList<Grid>();

            Iterator<Grid> it = tmp.iterator();
            Grid first = it.next();
            while (it.hasNext()) {
                Grid second = it.next();

                int fx = first.getXpos();
                int fy = first.getYpos();
                int sx = second.getXpos();
                int sy = second.getYpos();

                while (fx != sx || fy != sy) {
                    if (fx < sx) {
                        fx++;
                    } else if (fx > sx) {
                        fx--;
                    } else if (fy < sy) {
                        fy++;
                    } else if (fy > sy) {
                        fy--;
                    }
                    int nx = offsetX + fx * g1.getWidth();
                    int ny = offsetY + fy * g1.getHeight();

                    Grid tmpG = new Grid(g1.getBitmap());
                    tmpG.setLocation(nx, ny);
                    tmpG.setVisible(true);
                    tmpgs.add(tmpG);
                    getSprites().add(tmpG);
                    try {
                        sleep(20L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                first = second;
            }
            for (Grid t : tmpgs) {
                t.setVisible(false);
                getSprites().remove(t);
                try {
                    sleep(20L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            for (int i = 0; i < 5; i++) {
                g1.setImage(RSL.one().getKill(i));
                g4.setImage(RSL.one().getKill(i));
                try {
                    sleep(30L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            grids.incre();
            tmp.clear();
            g1.setVisible(false);
            g4.setVisible(false);
        }
    }
}
